﻿#pragma once
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <string> 
#include <CommCtrl.h>
#include <unordered_map>
#include <functional>
#include <shellapi.h>
#include <iostream>

#include <objidl.h>

#include <uxtheme.h>
#include "zyBuffGraphics.h"

#include "zyUIStruct.h"//引入的自定义宏/枚举/数据类型

#define ZY_DISABLE_COPY(Class) Class(const Class &) = delete; Class &operator=(const Class &) = delete;
#define ZY_DISABLE_MOVE(Class) Class(Class &&) = delete; Class &operator=(Class &&) = delete;
#define ZY_DISABLE_COPY_MOVE(Class) ZY_DISABLE_COPY(Class) ZY_DISABLE_MOVE(Class)



//@模块名称  黑月界面类模块
//@版本  1.0
//@日期  2024-08-07
//@作者  易团雪,感谢:逸辰Arne,飞等大佬的技术支持  
//@模块备注 本模块翻译与整理自易语言黑月界面类,

//@命名空间      DarkMoonUI
//@命名空间别名  黑月UI
//@隐藏{
namespace DarkMoonUI {
//@隐藏}
    // 前向申明
    class zyObject;
    class zyWindow;

    typedef LRESULT(WINAPI* FnWndProc)(zyObject*, HWND, UINT, WPARAM, LPARAM, BOOL*);
    typedef LRESULT(WINAPI* FnChildWndProc)(zyObject*, HWND, UINT, WPARAM, LPARAM, BOOL*);
    typedef void(WINAPI* FnDestroy)(zyObject*);

    int 黑月默认ID();
    RECT zyStringToRECT(const wchar_t* wstr);
    bool zyPathRemoveFileSpec(wchar_t* path);
    void setCurrentDirectoryToProcessDirectory();
    void SaveBinaryToHeaderFile(const std::vector<unsigned char>& data, const std::wstring& headerFilePath, const std::wstring& arrayName);
    std::vector<BYTE> ReadFileToBinary(const std::wstring& filePath);//跨平台兼容性
    BOOL zyReadFile(LPCWSTR filePath, std::vector<CHAR>* retData);
    BOOL preTranslateMessage(HWND hWnd, zyObject* this_, MSG& msg);
    static LRESULT WINAPI WndProc_(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    ATOM MyRegisterClass(HINSTANCE hInstance, const std::wstring& 参数_类名, WNDPROC 参数_窗口过程, HICON 参数_图标句柄, int 参数_类风格);

    // 环境App类
    class zyApplications {
    public:
        static zyApplications& getInstance() {
            static zyApplications instance;
            return instance;
        }

        //private 构造函数不能私有
        zyApplications();// : m_hInst(GetModuleHandle(NULL)), m_bEnableDpiConvert(FALSE) {}
        ~zyApplications();

        zyApplications(const zyApplications&) = delete;
        zyApplications& operator=(const zyApplications&) = delete;

        void 初始化(HINSTANCE hInstance = NULL, BOOL 参数_使用ATL = FALSE, UINT 参数_通用控件类 = 0);
      
        int 运行(zyWindow& bform, BOOL Bshow = TRUE);

        int AtlAxWinInit_();
        std::wstring GetDirectory() const;
        int 取命令行(std::vector<std::wstring>& 参数_命令行参数);
        std::wstring GetFileName();
        std::wstring GetRoute();
        void 结束();

        int getDpiForWindow() {
            HDC hdc = GetDC(NULL);
            int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
            int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
            ReleaseDC(NULL, hdc);
            return (((dpiX) > (dpiY)) ? (dpiX) : (dpiY));
        };
        void dpiConvert(POINT& pt) {
            if (!m_bEnableDpiConvert)
                return;

            //auto getDpiForWindow = []() -> int {
            //    HDC hdc = GetDC(NULL);
            //    int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
            //    int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
            //    //ReleaseDC(NULL, hdc);
            //    return (((dpiX) > (dpiY)) ? (dpiX) : (dpiY));
            //};

            static int dpi = getDpiForWindow();
            pt.x = (LONG)((pt.x * dpi) / 96.0);
            pt.y = (LONG)((pt.y * dpi) / 96.0);
        }

        void enableDpiConvert(BOOL bEnable) {
            m_bEnableDpiConvert = bEnable;
        }

        void registerWnd(HWND hWnd, zyObject* pObject) {
            m_wndEventMap[hWnd] = pObject;
        }

        void unregisterWnd(HWND hWnd) {
            m_wndEventMap.erase(hWnd);
        }

        zyObject* getWndObject(HWND hWnd) {
            auto it = m_wndEventMap.find(hWnd);
            if (it != m_wndEventMap.end())
                return it->second;
            return nullptr;
        }

        HINSTANCE getHandle() const {
            return m_hInst;
        }

        void setHandle(HINSTANCE hInst) {
            m_hInst = hInst;
        }

    private:
        HINSTANCE m_hInst;
        BOOL m_bEnableDpiConvert;
        std::unordered_map<HWND, zyObject*> m_wndEventMap;
        ULONG_PTR m_pGdiToken = 0;
    };

    using zyEnv = zyApplications;

    // 抽象基类
    class MemberFunctionCallerBase {
    public:
        virtual ~MemberFunctionCallerBase() = default;
        virtual void Call() = 0;
    };

    // 回调注册类
    template <typename R, typename... Args>
    class MemberFunctionCaller : public MemberFunctionCallerBase {
    private:
        std::function<R(Args...)> func; // 使用 std::function 存储可调用对象

    public:
        // 绑定成员函数
        template <typename C>
        MemberFunctionCaller(C* object, R(C::* memberFunc)(Args...)) {
            func = [object, memberFunc](Args... args) -> R {
                return (object->*memberFunc)(args...);
                };
        }

        // 绑定自由函数
        MemberFunctionCaller(R(*freeFunc)(Args...)) {
            func = [freeFunc](Args... args) -> R { return freeFunc(args...); };
        }

        // 调用函数
        R Call(Args... arguments) {
            return func(arguments...);
        }

        // 实现基类的纯虚函数
        void Call() override {}
    };

    // 回调触发类
    class TRegEvent {
    public:
        std::unique_ptr<MemberFunctionCallerBase> m_pBind; // 使用智能指针管理资源

        TRegEvent() = delete;

        explicit TRegEvent(MemberFunctionCallerBase* pBind) : m_pBind(pBind) {}

        ~TRegEvent() = default; // 不需要手动释放资源

        // 调用回调函数
        template <typename T, typename... Args>
        T handler(Args... args) {
            auto* caller = static_cast<MemberFunctionCaller<T, Args...>*>(m_pBind.get());
            if (caller) {
                return caller->Call(args...);
            }
            throw std::runtime_error("Invalid callback type");
        }
    };

    // 注册成员函数回调
    template <typename R, typename C, typename... Args>
    TRegEvent* TRegEventCallBack(C* c, R(C::* func)(Args...)) {
        return new TRegEvent(new MemberFunctionCaller<R, Args...>(c, func));
    }

    // 注册自由函数回调
    template <typename R, typename... Args>
    TRegEvent* TRegEventCallBack(R(*func)(Args...)) {
        return new TRegEvent(new MemberFunctionCaller<R, Args...>(func));
    }

    //@备注 注册C函数使用
    //函数支持任意类型
    //@别名 注册事件C_取地址(事件函数)
    #define TRegEventC_Ptr(mFun)  TRegEventCallBack(mFun,#mFun)
    //@备注 注册类回调使用,取得事件类地址,需要使用类名一起，如:&类名::函数名
    //函数支持任意类型
    //@别名 注册事件CPP_取地址(事件函数)
    #define TRegEventCPP_Ptr(mFun)  TRegEventCallBack(this,mFun,#mFun)


    //// 回调注册类
    //template <typename R, typename... Args>
    //class MemberFunctionCaller : public MemberFunctionCallerBase {
    //private:
    //    std::function<R(Args...)> func;

    //public:
    //    template <typename C>
    //    MemberFunctionCaller(C* object, R(/*__stdcall*/ C::* memberFunc)(Args...)) {
    //        func = [object, memberFunc](Args... args) -> R {
    //            return (object->*memberFunc)(args...);
    //            };
    //    }

    //    MemberFunctionCaller(R(__stdcall* freeFunc)(Args...)) {
    //        func = [freeFunc](Args... args) -> R { return freeFunc(args...); };
    //    }

    //    R Call(Args... arguments) {
    //        return func(arguments...);
    //    }

    //    void Call() override {};
    //};
    //// 回调触发类
    //class TRegEvent {
    //public:
    //    MemberFunctionCallerBase* m_pBind = nullptr;

    //    TRegEvent() = delete;

    //    TRegEvent(MemberFunctionCallerBase* pBind) : m_pBind(pBind) {}

    //    ~TRegEvent() { delete m_pBind; }

    //    template <typename T, typename... Args>
    //    T handler(Args... args) {
    //        return static_cast<MemberFunctionCaller<T, Args...>*>(m_pBind)->Call(args...);
    //    }
    //};

    //template <typename R, typename C, typename... Args>
    //TRegEvent* TRegEventCallBack(C* c, R(/*__stdcall*/ C::* func)(Args...)) {
    //    return new TRegEvent((MemberFunctionCallerBase*)(new MemberFunctionCaller<R, Args...>(c, func)));
    //}

    //template <typename R, typename... Args>
    //TRegEvent* TRegEventCallBack(R(__stdcall* func)(Args...)) {
    //    return new TRegEvent((MemberFunctionCallerBase*)(new MemberFunctionCaller<R, Args...>(func)));
    //}


}
